<?php
/**
 * EGP Framework
 *
 * LICENSE
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 */

!defined('EGP_LIB_DIR') && die('Access Deny!');

/**
 * 网银支付
 *
 * @package    classes
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 */
class EGP_Payment_Adapter_Chinabank extends EGP_Payment_Adapter_Abstract
{
    /**
     * 支付方式参数
     *
     * @var array
     */
    protected $_config = array(
        'v_mid' => null, //商户编号
        'v_oid' => null, //订单编号(日期(yyyymmdd)-商户编号-商户流水号，所有字符总和不可超过64位)
        'v_amount' => null, //订单总金额
        'v_moneytype' => 'CNY', //币种(CNY为人民币)
        'v_url' => null, //订单完成的返回页面
        'v_md5info' => null, //MD5校验码
        //------------------------------ 以上必填
        'remark1' => null, //备注1
        'remark2' => null, //备注2
        'v_rcvname' => null, //收货人姓名
        'v_rcvaddr' => null, //收货人地址
        'v_rcvtel' => null, //收货人电话
        'v_rcvpost' => null, //收货人邮编
        'v_rcvemail' => null, //收货人Email
        'v_rcvmobile' => null, //收货人手机号
        'v_ordername' => null, //订货人姓名
        'v_orderaddr' => null, //订货人地址
        'v_ordertel' => null, //订货人电话
        'v_orderpost' => null, //订货人邮编
        'v_orderemail' => null, //订货人Email
        'v_ordermobile' => null, //订货人手机号
        'key' => null, //商户密钥
    );

    /**
     * 商户订单编号
     *
     * @var string
     */
    protected $_id = null;

    /**
     * 付款提交方法
     *
     * @var string
     */
    protected $_method = 'POST';

    /**
     * 设置订单编号
     *
     * @param  string  $id
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setId($id)
    {
        if (!preg_match('/^\w{10,32}$/', $id)) {
            throw new EGP_Exception('无效的订单编号');
        }

        $this->_id = $id;

        return $this;
    }

    /**
     * 设置商户编号
     *
     * @param  string  $id
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVMid($id)
    {
        if (!preg_match('/^\d{4,10}$/', $id)) {
            throw new EGP_Exception('无效的商户编号');
        }

        $this->_config['v_mid'] = $id;

        return $this;
    }

    /**
     * 设置订单编号
     *
     * @param  string  $id
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVOid($id)
    {
        if (!preg_match('/^\d{8}\-\d{4,10}\-\w{10,32}$/', $id)) {
            throw new EGP_Exception('无效的订单编号');
        }

        $this->_config['v_oid'] = $id;

        return $this;
    }

    /**
     * 设置订单主题(使用remark代理)
     *
     * @param  string  $subject
     * @return EGP_Payment_Adapter_Chinabank
     */
    public function setSubject($subject)
    {
        $this->_config['remark1'] = str_break(trim(strip_tags((string) $subject)), 150);

        return $this;
    }

    /**
     * 设置订单总金额
     *
     * @param  float  $amount
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setAmount($amount)
    {
        if (!$this->_isFloat($amount) || floatval($amount) <= 0) {
            throw new EGP_Exception('无效的订单总金额');
        }

        $this->_config['v_amount'] = $amount;

        return $this;
    }

    /**
     * 设置订单总金额
     *
     * @param  float  $amount
     * @return EGP_Payment_Adapter_Chinabank
     */
    public function setVAmount($amount)
    {
        return $this->setAmount($amount);
    }

    /**
     * 设置交易货币类型
     *
     * @param  string  $code
     * @return EGP_Payment_Adapter_Chinabank
     */
    public function setVMoneytype($code)
    {
        return $this;
    }

    /**
     * 设置支付响应 URL
     *
     * 处理完成后返回的 URL
     *
     * @param  string  $url
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVUrl($url)
    {
        if (!empty($url) && !$this->_isUrl($url)) {
            throw new EGP_Exception('无效的支付响应 URL');
        }

        $this->_config['v_url'] = (string) $url;

        return $this;
    }

    /**
     * 设置 MD5 校验码
     *
     * @param  string  $code
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVMd5info($code)
    {
        if (!preg_match('/[a-z0-9]{32}/i', $code)) {
            throw new EGP_Exception('无效的 md5 校验值');
        }

        $this->_config['v_md5info'] = strtoupper($code);

        return $this;
    }

    /**
     * 设置备注字段 1
     *
     * @param  string  $remark
     * @return EGP_Payment_Adapter_Chinabank
     */
    public function setRemark1($remark)
    {
        return $this->setSubject($remark);
    }

    /**
     * 设置备注字段 2
     *
     * @param  string  $remark
     * @return EGP_Payment_Adapter_Chinabank
     */
    public function setRemark2($remark)
    {
        $this->_config['remark2'] = str_break(trim(strip_tags((string) $remark)), 150);

        return $this;
    }

    /**
     * 设置收货人姓名
     *
     * @param  string  $name
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVRcvname($name)
    {
        if (!empty($name)) {
            if (strlen($name) > 80) {
                throw new EGP_Exception('收货人姓名不能大于 80 个字符');
            }

            $this->_config['v_rcvname'] = (string) $name;
        }

        return $this;
    }

    /**
     * 设置收货人地址
     *
     * @param  string  $address
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVRcvaddr($address)
    {
        if (!empty($address)) {
            if (strlen($address) > 200) {
                throw new EGP_Exception('收货人地址不能大于 200 个字符');
            }

            $this->_config['v_rcvaddr'] = (string) $address;
        }

        return $this;
    }

    /**
     * 设置收货人电话号码
     *
     * @param  string  $phone
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVRcvtel($phone)
    {
        if (!empty($phone)) {
            if (!$this->_isPhone($phone)) {
                throw new EGP_Exception('无效的收货人电话号码');
            }
            $this->_config['v_rcvtel'] = (string) $phone;
        }

        return $this;
    }

    /**
     * 设置收货人邮政编码
     *
     * @param  string  $zip
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVRcvpost($zip)
    {
        if (!empty($zip)) {
            if (!$this->_isZip($zip)) {
                throw new EGP_Exception('无效的收货人邮政编码');
            }

            $this->_config['v_rcvpost'] = (string) $zip;
        }

        return $this;
    }

    /**
     * 设置收货人 Email
     *
     * @param  string  $email
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVRcvemail($email)
    {
        if (!empty($email)) {
            if (strlen($email) <= 100 && $this->_isMail($email)) {
                $this->_config['v_rcvemail'] = (string) $email;
            } else {
                throw new EGP_Exception('无效的收货人 Email');
            }
        }

        return $this;
    }

    /**
     * 设置收货人手机号码
     *
     * @param  string  $mobile
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVRcvmobile($mobile)
    {
        if (!empty($mobile)) {
            if (strlen($email) <= 13 && $this->_isMobile($mobile)) {
                throw new EGP_Exception('无效的收货人手机号码');
            }

            $this->_config['v_rcvmobile'] = (string) $mobile;
        }

        return $this;
    }

    /**
     * 设置订货人姓名
     *
     * @param  string  $name
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVOrdername($name)
    {
        if (!empty($name)) {
            if (strlen($name) > 80) {
                throw new EGP_Exception('订货人姓名不能大于 80 个字符');
            }

            $this->_config['v_ordername'] = (string) $name;
        }

        return $this;
    }

    /**
     * 设置订货人地址
     *
     * @param  string  $address
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVOrderaddr($address)
    {
        if (!empty($address)) {
            if (strlen($address) > 200) {
                throw new EGP_Exception('订货人地址不能大于 200 个字符');
            }

            $this->_config['v_orderaddr'] = (string) $address;
        }

        return $this;
    }

    /**
     * 设置订货人电话号码
     *
     * @param  string  $phone
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVOrdertel($phone)
    {
        if (!empty($phone)) {
            if (!$this->_isPhone($phone)) {
                throw new EGP_Exception('无效的订货人电话号码');
            }
            $this->_config['v_ordertel'] = (string) $phone;
        }

        return $this;
    }

    /**
     * 设置订货人邮政编码
     *
     * @param  string  $zip
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVOrderpost($zip)
    {
        if (!empty($zip)) {
            if (!$this->_isZip($zip)) {
                throw new EGP_Exception('无效的订货人邮政编码');
            }

            $this->_config['v_orderpost'] = (string) $zip;
        }

        return $this;
    }

    /**
     * 设置订货人 Email
     *
     * @param  string  $email
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVOrderemail($email)
    {
        if (!empty($email)) {
            if (strlen($email) <= 100 && $this->_isMail($email)) {
                $this->_config['v_orderemail'] = (string) $email;
            } else {
                throw new EGP_Exception('无效的订货人 Email');
            }
        }

        return $this;
    }

    /**
     * 设置订货人手机号码
     *
     * @param  string  $mobile
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setVOrdermobile($mobile)
    {
        if (!empty($mobile)) {
            if (strlen($email) <= 13 && $this->_isMobile($mobile)) {
                throw new EGP_Exception('无效的订货人手机号码');
            }

            $this->_config['v_ordermobile'] = (string) $mobile;
        }

        return $this;
    }

    /**
     * 设置商户密钥
     *
     * @param  string  $key
     * @return EGP_Payment_Adapter_Chinabank
     * @throws EGP_Exception
     */
    public function setKey($key)
    {
        if (empty($key)) {
            throw new EGP_Exception('商户密钥不能为空');
        }

        if (!is_string($key) || !preg_match('/[a-z0-9]{6}/i', $key)) {
            throw new EGP_Exception('无效的商户密钥');
        }

        $this->_config['key'] = (string) $key;

        return $this;
    }

    /**
     * 获取支付网关地址
     *
     * @return string
     */
    public function getGateWay()
    {
        return 'https://pay3.chinabank.com.cn/PayGate';
    }

    /**
     * 获取支付 URL
     *
     * @return string
     */
    public function getPayUrl()
    {
        return $this->getGateWay();
    }

    /**
     * 对参数进行校验
     *
     * @return boolean
     */
    public function isValid()
    {
        if (null == $this->_config['v_oid']) {
            $this->_config['v_oid'] = date('Ymd-') . $this->_config['v_mid'] . '-' . $this->_id;
        }
        if (null == $this->_config['v_md5info']) {
            $this->_config['v_amount'] = number_format($this->_config['v_amount'], 2, '.', '');
            $this->_config['v_md5info'] = md5($this->_config['v_amount'] . $this->_config['v_moneytype'] .
                                          $this->_config['v_oid'] . $this->_config['v_mid'] .
                                          $this->_config['v_url'] . $this->_config['key']);
        }
        return parent::isValid();
    }

    /**
     * 获取表单提交参数
     *
     * @return array
     */
    public function getParams()
    {
        $params = $this->_config;
        unset($params['key']);
        foreach($params as $key => $value) {
            if ($value == '' || $value == null) {
                unset($params[$key]);
            }
        }
        return $params;
    }

}